﻿using System;
using System.Collections.Generic;
using System.Xml;

namespace Share
{
    public class XmlLoader
    {
        private readonly object _lock = new object();
        private Dictionary<string, string> m_mapData = new Dictionary<string, string>();

        /// <summary>
        /// 加载 XML 字符串
        /// </summary>
        public bool LoadText(string strText)
        {
            try
            {
                lock (_lock)
                {
                    m_mapData.Clear();
                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.LoadXml(strText); // 加载 XML 字符串
                    var data = (XmlNode)xmlDoc.SelectSingleNode("/root/Config");
                    if (data == null) return false;

                    ParseChildNodes(data.ChildNodes);
                    OnInit();
                }
                return true;
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine($"LoadText failed: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 加载 XML 文件
        /// </summary>
        public void Load(string strFileName)
        {
            try
            {
                lock (_lock)
                {
                    m_mapData.Clear();
                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.Load(strFileName); // 加载 XML 文件
                    var data = (XmlNode)xmlDoc.SelectSingleNode("/root/Config");
                    if (data == null) return;

                    ParseChildNodes(data.ChildNodes);
                    OnInit();
                }
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine($"Load failed: {ex.Message}");
            }
        }

        /// <summary>
        /// 设置键值对
        /// </summary>
        public void SetValue(string strKey, string strValue)
        {
            lock (_lock)
            {
                m_mapData.Add(strKey, strValue);
            }
        }

        /// <summary>
        /// 保存为 XML 文件
        /// </summary>
        public void Fresh(string fullName)
        {
            try
            {
                using (var writer = XmlWriter.Create(fullName, new XmlWriterSettings { Indent = true }))
                {
                    writer.WriteStartDocument();
                    writer.WriteStartElement("root");

                    writer.WriteStartElement("Config");
                    foreach (var item in m_mapData)
                    {
                        writer.WriteStartElement("Item");
                        writer.WriteAttributeString(item.Key, item.Value);
                        writer.WriteEndElement();
                    }

                    writer.WriteEndElement(); // Config
                    writer.WriteEndElement(); // root
                    writer.WriteEndDocument();
                }
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine($"Fresh failed: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取整数值
        /// </summary>
        public int GetValueInt(string strKey)
        {
            if (m_mapData.TryGetValue(strKey, out var value))
            {
                try
                {
                    return Convert.ToInt32(value);
                }
                catch
                {
                    Console.Error.WriteLine($"Invalid integer value for key: {strKey}");
                }
            }
            return -1;
        }

        /// <summary>
        /// 获取浮点数值
        /// </summary>
        public double GetValueFloat(string strKey)
        {
            if (m_mapData.TryGetValue(strKey, out var value))
            {
                try
                {
                    return Convert.ToDouble(value);
                }
                catch
                {
                    Console.Error.WriteLine($"Invalid float value for key: {strKey}");
                }
            }
            return 0;
        }

        /// <summary>
        /// 获取字符串值
        /// </summary>
        public string GetValueString(string strKey)
        {
            if (m_mapData.TryGetValue(strKey, out var value))
            {
                return value;
            }
            Console.Error.WriteLine($"Key not found: {strKey}");
            return "";
        }

        /// <summary>
        /// 解析子节点
        /// </summary>
        private void ParseChildNodes(XmlNodeList nodeList)
        {
            foreach (var item in nodeList)
            {
                if (item is XmlElement element)
                {
                    string key = element.LocalName;
                    string value = element.InnerText;
                    m_mapData.Add(key, value);
                }
            }
        }

        /// <summary>
        /// 初始化回调
        /// </summary>
        protected virtual void OnInit() { }

        /// <summary>
        /// 获取浮点数（静态方法）
        /// </summary>
        public static float GetFloat(XmlElement e, string strKey)
        {
            var item = (XmlElement)e.SelectSingleNode(strKey);
            if (item != null)
            {
                try
                {
                    return (float)Convert.ToDouble(item.InnerText);
                }
                catch
                {
                    Console.Error.WriteLine($"Invalid float value for key: {strKey}");
                }
            }
            return 0;
        }

        /// <summary>
        /// 获取整数（静态方法）
        /// </summary>
        public static int GetInt(XmlElement e, string strKey)
        {
            var item = (XmlElement)e.SelectSingleNode(strKey);
            if (item != null)
            {
                try
                {
                    return Convert.ToInt32(item.InnerText);
                }
                catch
                {
                    Console.Error.WriteLine($"Invalid integer value for key: {strKey}");
                }
            }
            return 0;
        }
    }
}